package com.haikesi.api.platform.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.haikesi.api.base.Error;
import com.haikesi.api.base.*;
import com.haikesi.api.device.dao.DeviceDao;
import com.haikesi.api.device.domain.po.DevicePO;
import com.haikesi.api.device.service.IDeviceService;
import com.haikesi.api.platform.dao.PlatformParamDao;
import com.haikesi.api.platform.domain.po.PlatformParamPo;
import com.haikesi.api.platform.domain.vo.PlatformParamSearchVo;
import com.haikesi.api.platform.domain.vo.PlatformParamUpdateVo;
import com.haikesi.api.platform.service.IPlatformParamService;
import com.haikesi.api.subscribertable.dao.SubscriberTableDao;
import com.haikesi.api.subscribertable.domain.po.SubscriberTablePo;
import com.haikesi.exception.BusinessException;
import com.haikesi.util.ApcosApiUtils;
import com.haikesi.util.LogApiUtils;
import com.haikesi.util.RestTemplateUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @version V1.0
 * @ClassName: PlatformParamServiceImpl
 * @Description: TODO(用一句话描述该文件做什么)
 * @author: zqy
 * @date: 2019年5月14日 下午4:27:00
 * @Copyright: 2019 重庆海克斯科技有限公司.
 * 注意：本内容仅限于重庆海克斯科技有限公司内部传阅，禁止外泄以及用于其他的商业目
 */
@Service
@Transactional
public class PlatformParamServiceImpl implements IPlatformParamService {
    private static Log log = LogFactory.getLog(PlatformParamServiceImpl.class);

    @Autowired
    private PlatformParamDao platformParamDao;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private SubscriberTableDao subscriberTableDao;
    @Autowired
    DeviceDao deviceDao;
    @Autowired
    private IDeviceService deviceService;
    /**
     * 获取平台参数表数据
     */
    @Override
    public List<PlatformParamSearchVo> getList(String platformType) {
        Example example = new Example(PlatformParamPo.class);
        example.and().andEqualTo("platformType", platformType);
        List<PlatformParamPo> list = platformParamDao.selectByExample(example);
        if (list.size() > 1) {
            throw new BusinessException(Type.EXCEPTION, ErrorTools.ErrorAsArrayList(new Error("PlatformParamError", "数据异常请联系管理员")));
        }
        List<PlatformParamSearchVo> listVo = new ArrayList<PlatformParamSearchVo>();
        if (list.size() > 0) {
            for (PlatformParamPo platformParamPo : list) {
                PlatformParamSearchVo platformParamSearchVo = new PlatformParamSearchVo();
                BeanUtils.copyProperties(platformParamPo, platformParamSearchVo);
                listVo.add(platformParamSearchVo);
            }
        }

        return listVo;
    }

    /**
     * 新增或者修改平台参数
     */
    @Override
    public void update(PlatformParamUpdateVo platformParamUpdateVo) {
        PlatformParamPo platformParamPo = new PlatformParamPo();
        BeanUtils.copyProperties(platformParamUpdateVo, platformParamPo);
        if (StringUtils.isNotBlank(platformParamUpdateVo.getId())) {
            PlatformParamPo po = platformParamDao.selectByPrimaryKey(platformParamUpdateVo.getId());
            if(po == null) {
                throw new BusinessException(Type.NOT_FOUND_ERROR, ErrorTools.ErrorAsArrayList(new Error("id", "参数异常")));
            }
            platformParamPo.preUpdate();
            int i = platformParamDao.updateByPrimaryKeySelective(platformParamPo);
            if (i == Constants.SQL_RETUN_SUCCESS) {
                throw new BusinessException(Type.FORMAT_EXCEPTION);
            }
            if(platformParamPo.getPlatformType().equals(1)){
                if(!platformParamUpdateVo.getCallBackUrl().equals(po.getCallBackUrl())) {
                    ApcosApiUtils.getToken(platformParamUpdateVo.getServiceId(), platformParamUpdateVo.getCallBackUrl(), platformParamUpdateVo.getServiceKey(), true);
                }
            }
        } else {
            Example example = new Example(PlatformParamPo.class);
            example.and().andEqualTo("platformType", platformParamPo.getPlatformType());
            List<PlatformParamPo> list = platformParamDao.selectByExample(example);
            if (list.size() > 0) {
                throw new BusinessException(Type.FORMAT_EXCEPTION, ErrorTools.ErrorAsArrayList(new Error("PlatformParamError", "数据异常请联系管理员")));
            }
            platformParamPo.preInsert();
            int i = platformParamDao.insertSelective(platformParamPo);
            if (i == Constants.SQL_RETUN_SUCCESS) {
                new BusinessException(Type.EXCEPTION_FAIL);
            }
        }
        String platformType1 = platformParamUpdateVo.getPlatformType();

        getKeyAndId(platformType1);
    }

    public void getKeyAndId(String platformType) {
        List<PlatformParamSearchVo> listVo = getList(platformType);
        PlatformParamSearchVo pv = new PlatformParamSearchVo();
        if (listVo.size() == 1) {
            for (PlatformParamSearchVo platformParamSearchVo : listVo) {
                BeanUtils.copyProperties(platformParamSearchVo, pv);
            }
        } else {
            throw new BusinessException(Type.EXCEPTION, ErrorTools.ErrorAsArrayList(new Error("PlatformParamError", "数据异常请联系管理员")));
        }
        if(pv.getPlatformType().equals("1")){
            redisUtils.set(Constants.SERVICE_KEY, pv.getServiceKey());
            redisUtils.set(Constants.SERVICE_ID, pv.getServiceId());
            redisUtils.set(Constants.SERVICE_BACK_URL, pv.getCallBackUrl());
            redisUtils.set(Constants.SERVICE_URL, pv.getUrl());
        } else if(pv.getPlatformType().equals("2")){
            redisUtils.set(Constants.BIG_APP_KEY, pv.getServiceKey());
            redisUtils.set(Constants.BIG_APP_ID, pv.getServiceId());
            redisUtils.set(Constants.BIG_AP_ID, pv.getApId());
            redisUtils.set(Constants.BIG_SERVICE_URL, pv.getUrl());
        } else {
            redisUtils.set(Constants.KF_SERVICE_KEY, pv.getServiceKey());
            redisUtils.set(Constants.KF_SERVICE_ID, pv.getServiceId());
            redisUtils.set(Constants.KF_SERVICE_URL, pv.getUrl());
        }
    }


    /**
     * 平台回调
     *
     * @param params
     * @return
     */
    @Override
    public String callback_operation(HashMap<String, Object> params) {
        log.info(">>>>>>>>>>>处理平台回调......");
        log.info(">>>>>>>>>>>平台回调值：" + params.toString());
        //校验参数中是否拥有code 和data 参数 并且两个不等于空
        if (!params.containsKey(Constants.AOPIS_CALLBACK_CODE_NAME) || !params.containsKey(Constants.AOPIS_CALLBACK_DATA_NAME)) {
            return Constants.RETUN_FAIL_STRING;
        }
        if (StringUtils.isBlank(String.valueOf(params.get(Constants.AOPIS_CALLBACK_CODE_NAME))) || StringUtils.isBlank(String.valueOf(params.get(Constants.AOPIS_CALLBACK_DATA_NAME)))) {
            return Constants.RETUN_FAIL_STRING;
        }
        String code = String.valueOf(params.get(Constants.AOPIS_CALLBACK_CODE_NAME));
        String data = JSONObject.toJSONString(params.get(Constants.AOPIS_CALLBACK_DATA_NAME));

        LogApiUtils.add_Sys_Log("bcca网关",data,"设备上报信息","");

        switch (code) {
            case Constants.AOPIS_CALLBACK_CODE_SUBSCRIPTION:
                if(op_callback_subscription(data)==Constants.RETUN_FAIL){
                    return Constants.RETUN_FAIL_STRING;
                }
                break;
            case  Constants.AOPIS_CALLBACK_CODE_REPORTMESSAGE:
                if(op_callback_reportMessage(data)==Constants.RETUN_FAIL){
                    return Constants.RETUN_FAIL_STRING;
                }
                break;
            case  Constants.AOPIS_CALLBACK_CODE_PRODUCTUPDATE:
                if(op_callback_productUpdate(data)==Constants.RETUN_FAIL){
                    return Constants.RETUN_FAIL_STRING;
                }
                break;
            default:
                return Constants.RETUN_FAIL_STRING;
        }
        log.info(">>>>>>>>>>>平台处理回调成功<<<<<<<<<<<");
        return Constants.RETUN_SUCCESS_STRING;
    }

    private Integer op_callback_productUpdate(String data) {
        log.info(">>>>>>>>>>>处理设备更新回调.....<<<<<<<<<<<");
        JSONObject result = JSON.parseObject(data);
        String account = String.valueOf(result.get("account"));
        if (StringUtils.isBlank(account)) {
            return Constants.RETUN_FAIL;
        }
        Example example = new Example(SubscriberTablePo.class);
        example.and().andEqualTo("subscriberNumber", account);
        SubscriberTablePo po = subscriberTableDao.selectOneByExample(example);
        if(po==null||po.getSubscriberState()!=Constants.SUBSCRIBER_STATE_2){
            log.info(">>>>>>>>>>>订阅账号未找到.....<<<<<<<<<<<");
            return Constants.RETUN_FAIL;
        }
        String type = String.valueOf(result.get("type"));
        if(type.equals(Constants.AOPIS_CALLBACK_CODE_PRODUCTUPDATE_TYPE_ADD)){
            //当type为add(新增)的时候，批量新增，id为空串，第三方服务只需要对该账号的数据进行增量更新即可
            deviceService.importApcosDervice(account);
            return Constants.RETUN_SUCCESS;
        }
        if(type.equals(Constants.AOPIS_CALLBACK_CODE_PRODUCTUPDATE_TYPE_DELETE)){
            //type为delete（删除）的时候，id为被删除记录的id，第三方系统只需要在本地做删除即可。
            deviceService.deleteBySerialNum(String.valueOf(result.get("id")),account);
            return Constants.RETUN_SUCCESS;
        }
        return Constants.RETUN_SUCCESS;
    }

    /**
     * 处理报警回调
     * @param data
     * @return
     */
    private Integer op_callback_reportMessage(String data) {
        log.info(">>>>>>>>>>>处理报警回调.....<<<<<<<<<<<");
        JSONObject result = JSON.parseObject(data);
        String account = String.valueOf(result.get("account"));
        if (StringUtils.isBlank(account)) {
            return Constants.RETUN_FAIL;
        }
        Example example = new Example(SubscriberTablePo.class);
        example.and().andEqualTo("subscriberNumber", account);
        SubscriberTablePo po = subscriberTableDao.selectOneByExample(example);
        if(po==null||po.getSubscriberState()!=Constants.SUBSCRIBER_STATE_2){
            log.info(">>>>>>>>>>>订阅账号未找到.....<<<<<<<<<<<");
            return Constants.RETUN_FAIL;
        }
        if(StringUtils.isBlank(po.getCallbackUrl())){
            log.info(">>>>>>>>>>>订阅账号未设置报警回调.....<<<<<<<<<<<");
            return Constants.RETUN_FAIL;
        }
        log.info(">>>>>>>>>>result:"+result);
        Example exampleDevice = new Example(DevicePO.class);
        exampleDevice.and().andEqualTo("serialNum", result.get("serial_num"));
        DevicePO devicePO= deviceDao.selectOneByExample(exampleDevice);
        if (devicePO==null) {
            throw new BusinessException(Type.EXIST_ERROR, ErrorTools.ErrorAsArrayList(new Error("serialNum", "设备不存在")));
        }

        result.put("longitude",devicePO.getDeviceLongitude());
        result.put("latitude",devicePO.getDeviceLatitude());
        result.put("deviceName",devicePO.getDeviceName());

        JSONObject requestBody = new JSONObject();
        requestBody.put("data", result);
        log.info("===========请求URl:" + po.getCallbackUrl());
        log.info("===========请求参数:" + requestBody.toString());
        ResponseEntity<JSONObject> response = RestTemplateUtils.post(po.getCallbackUrl(), requestBody, JSONObject.class);
        log.info("===========ResponseEntity:" + response);
        return Constants.RETUN_SUCCESS;
    }


    /**
     * 处理订阅回调信息
     *
     * @param data
     */
    public int op_callback_subscription(String data) {
        log.info(">>>>>>>>>>>处理订阅回调信息.....<<<<<<<<<<<");
        //具体的结果json字符串subscrip_status 1通过 2未通过{"account":"C280001","subscrip_status":"1"}
        JSONObject result = JSON.parseObject(data);
        String account = String.valueOf(result.get("account"));
        String asubscrip_status = String.valueOf(result.get("subscrip_status"));
        if (StringUtils.isBlank(account) || StringUtils.isBlank(asubscrip_status)) {
            return Constants.RETUN_FAIL;
        }
        Example example = new Example(SubscriberTablePo.class);
        example.and().andEqualTo("subscriberNumber", account);
        SubscriberTablePo po = subscriberTableDao.selectOneByExample(example);
        if(po==null||po.getSubscriberState()!=Constants.SUBSCRIBER_STATE_1){
            log.info(">>>>>>>>>>>订阅账号未找到.....<<<<<<<<<<<");
            return Constants.RETUN_FAIL;
        }
//        po.setSubscriberState(Constants.SUBSCRIBER_STATE_3);
        if (asubscrip_status.equals(Constants.AOPIS_CALLBACK_SUBSCRIP_STATUS_2)) {
            //未通过
            po.setSubscriberState(Constants.SUBSCRIBER_STATE_3);
            po.preUpdate();
            subscriberTableDao.updateByPrimaryKeySelective(po);
            return Constants.RETUN_SUCCESS;
        }
        deviceService.importApcosDervice(po.getSubscriberNumber());
        return Constants.RETUN_SUCCESS;
    }
}
